์น ๋ธ๋ผ์ฐ์ ์์ ์์ ์ค๋์ค ์ํ ์ฒ๋ฆฌ๋ฅผ ์ํ WebCodecs AudioData๋ฅผ ํ์ํ์ธ์. ๊ณ ๊ธ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ ์ค๋์ค ๋์ฝ๋ฉ, ์ธ์ฝ๋ฉ, ์กฐ์์ ๋ง์คํฐํ์ธ์.
์์ ์ค๋์ค ํ์ ์ ๊ธ ํด์ : WebCodecs AudioData ์ฌ์ธต ๋ถ์
์น ํ๋ซํผ์ ์ ์ ์ธ ๋ฌธ์ ๋ทฐ์ด์์ ๋์ ์ด๊ณ ์ํธ์์ฉ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํ ๊ฐ๋ ฅํ ๋๊ตฌ๋ก ๊ทน์ ์ผ๋ก ๋ฐ์ ํ์ต๋๋ค. ์ด๋ฌํ ๋ฐ์ ์ ์ค์ฌ์๋ ํ๋ถํ ๋ฏธ๋์ด๋ฅผ ์ฒ๋ฆฌํ๋ ๋ฅ๋ ฅ์ด ์์ผ๋ฉฐ, ์น์์์ ์ค๋์ค ์ฒ๋ฆฌ๋ ์๋นํ ์ง์ ์ ์ด๋ฃจ์์ต๋๋ค. ์ค๋ซ๋์ Web Audio API๊ฐ ๊ณ ์์ค ์ค๋์ค ์กฐ์์ ์ด์์ด์์ง๋ง, ์์ ์ค๋์ค ๋ฐ์ดํฐ๋ฅผ ๋ ์ธ๋ฐํ๊ฒ ์ ์ดํ๊ณ ์ ํ๋ ๊ฐ๋ฐ์๋ค์ ์ํด ์๋ก์ด ์ฃผ์ญ์ด ๋ฑ์ฅํ์ต๋๋ค: AudioData ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ถ WebCodecs์
๋๋ค.
์ด ํฌ๊ด์ ์ธ ๊ฐ์ด๋๋ ์ฌ๋ฌ๋ถ์ WebCodecs AudioData์ ์ธ๊ณ๋ก ์๋ดํ ๊ฒ์
๋๋ค. ์ฐ๋ฆฌ๋ ์ด ์ธํฐํ์ด์ค์ ๊ธฐ๋ฅ๋ค์ ํ์ํ๊ณ , ๊ทธ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ฉฐ, ์ค์ฉ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์
์ ์์ฐํ๊ณ , ๊ฐ๋ฐ์๋ค์ด ๋ธ๋ผ์ฐ์ ๋ด์์ ์ง์ ์ ๊ตํ ์ค๋์ค ๊ฒฝํ์ ๊ตฌ์ถํ ์ ์๋๋ก ์ด๋ป๊ฒ ํ์ ์ค์ด์ฃผ๋์ง ๋
ผ์ํ ๊ฒ์
๋๋ค. ์ค๋์ค ์์ง๋์ด์ด๋ , ๋ฉํฐ๋ฏธ๋์ด์ ํ๊ณ๋ฅผ ๋ํ๋ ์น ๊ฐ๋ฐ์์ด๋ , ํน์ ๋จ์ํ ์น ์ค๋์ค์ ์ ์์ค ๋ฉ์ปค๋์ฆ์ ๋ํด ๊ถ๊ธํ ๋ถ์ด๋ , ์ด ๊ธ์ ์ฌ๋ฌ๋ถ์ด ์ค๋์ค ์ํ์ ์์์ ์ธ ํ์ ํ์ฉํ ์ ์๋ ์ง์์ ๊ฐ์ถ๊ฒ ํด์ค ๊ฒ์
๋๋ค.
์น ์ค๋์ค์ ์งํํ๋ ํ๊ฒฝ: WebCodecs๊ฐ ์ค์ํ ์ด์
์๋
๋์ Web Audio API(AudioContext)๋ ์ค๋์ค ํฉ์ฑ, ์ฒ๋ฆฌ, ์ฌ์์ ๊ฐ๋ ฅํ ๊ทธ๋ํ ๊ธฐ๋ฐ ์ ๊ทผ ๋ฐฉ์์ ์ ๊ณตํ์ต๋๋ค. ์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ค์ ๋ค์ํ ์ค๋์ค ๋
ธ๋(์ค์ค๋ ์ดํฐ, ํํฐ, ๊ฒ์ธ ์ปจํธ๋กค ๋ฑ)๋ฅผ ์ฐ๊ฒฐํ์ฌ ๋ณต์กํ ์ค๋์ค ํ์ดํ๋ผ์ธ์ ๋ง๋ค ์ ์์์ต๋๋ค. ๊ทธ๋ฌ๋ ์ธ์ฝ๋ฉ๋ ์ค๋์ค ํฌ๋งท(MP3, AAC, Ogg Vorbis ๋ฑ)์ ๋ค๋ฃจ๊ฑฐ๋ ๊ทธ๋ค์ ์์ ์ํ ๋ฐ์ดํฐ๋ฅผ ๊ทผ๋ณธ์ ์ธ ์์ค์์ ์ง์ ์กฐ์ํ๋ ๋ฐ ์์ด์ Web Audio API๋ ํ๊ณ๊ฐ ์์์ต๋๋ค:
- ์ธ์ฝ๋ฉ๋ ๋ฏธ๋์ด ๋์ฝ๋ฉ:
AudioContext.decodeAudioData()๋ ์ธ์ฝ๋ฉ๋ ์ค๋์ค ํ์ผ์AudioBuffer๋ก ๋์ฝ๋ฉํ ์ ์์์ง๋ง, ์ด๋ ์ผํ์ฑ์ ๋น๋๊ธฐ ์์ ์ด์๊ณ ์ค๊ฐ ๋์ฝ๋ฉ ๋จ๊ณ๋ฅผ ๋ ธ์ถํ์ง ์์์ต๋๋ค. ๋ํ ์ค์๊ฐ ์คํธ๋ฆผ ๋์ฝ๋ฉ์ ์ํด ์ค๊ณ๋์ง๋ ์์์ต๋๋ค. - ์์ ๋ฐ์ดํฐ ์ ๊ทผ:
AudioBuffer๋ ์์ PCM(ํ์ค ๋ถํธ ๋ณ์กฐ) ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ์ง๋ง, ์ด ๋ฐ์ดํฐ๋ฅผ ์กฐ์ํ๋ ค๋ฉด ์ข ์ข ์๋ก์ดAudioBuffer์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฑฐ๋ ๋ณํ์ ์ํดOfflineAudioContext๋ฅผ ์ฌ์ฉํด์ผ ํ์ต๋๋ค. ์ด๋ ํ๋ ์ ๋จ์ ์ฒ๋ฆฌ๋ ์ปค์คํ ์ธ์ฝ๋ฉ์ ๋ฒ๊ฑฐ๋ก์ธ ์ ์์์ต๋๋ค. - ๋ฏธ๋์ด ์ธ์ฝ๋ฉ: WebAssembly๋ก ํฌํ ๋ ์ธ์ฝ๋๋ ์๋ฒ ์ธก ์ฒ๋ฆฌ์ ์์กดํ์ง ์๊ณ ๋ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ์์ ์ค๋์ค๋ฅผ ์์ถ ํฌ๋งท์ผ๋ก ์ธ์ฝ๋ฉํ ์ ์๋ ๋ค์ดํฐ๋ธํ๊ณ ์ฑ๋ฅ ์ข์ ๋ฐฉ๋ฒ์ด ์์์ต๋๋ค.
WebCodecs API๋ ์ด๋ฌํ ๊ฒฉ์ฐจ๋ฅผ ๋ฉ์ฐ๊ธฐ ์ํด ๋์ ๋์์ต๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ์ ๋ฏธ๋์ด ๊ธฐ๋ฅ์ ๋ํ ์ ์์ค ์ ๊ทผ์ ์ ๊ณตํ์ฌ ๊ฐ๋ฐ์๊ฐ ์ค๋์ค ๋ฐ ๋น๋์ค ํ๋ ์์ ์ง์ ๋์ฝ๋ฉํ๊ณ ์ธ์ฝ๋ฉํ ์ ์๋๋ก ํฉ๋๋ค. ์ด๋ฌํ ์ง์ ์ ์ธ ์ ๊ทผ์ ๋ค์๊ณผ ๊ฐ์ ๋ฌดํํ ๊ฐ๋ฅ์ฑ์ ์ด์ด์ค๋๋ค:
- ์ค์๊ฐ ๋ฏธ๋์ด ์ฒ๋ฆฌ (์: ์ปค์คํ ํํฐ, ํจ๊ณผ).
- ์น ๊ธฐ๋ฐ ๋์งํธ ์ค๋์ค ์ํฌ์คํ ์ด์ (DAW) ๋๋ ๋น๋์ค ํธ์ง๊ธฐ ๊ตฌ์ถ.
- ์ปค์คํ ์คํธ๋ฆฌ๋ฐ ํ๋กํ ์ฝ ๋๋ ์ ์ํ ๋นํธ๋ ์ดํธ ๋ก์ง ๊ตฌํ.
- ํด๋ผ์ด์ธํธ ์ธก์์ ๋ฏธ๋์ด ํฌ๋งท ํธ๋์ค์ฝ๋ฉ.
- ๋ฏธ๋์ด ์คํธ๋ฆผ์ ๋ํ ๊ณ ๊ธ ๋ถ์ ๋ฐ ๋จธ์ ๋ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ .
WebCodecs์ ์ค๋์ค ๊ธฐ๋ฅ์ ์ค์ฌ์๋ ์์ ์ค๋์ค ์ํ์ ์ํ ํ์คํ๋ ์ปจํ
์ด๋ ์ญํ ์ ํ๋ AudioData ์ธํฐํ์ด์ค๊ฐ ์์ต๋๋ค.
AudioData ์ฌ์ธต ๋ถ์: ์์ ์ํ ์ปจํ ์ด๋
AudioData ์ธํฐํ์ด์ค๋ ๋จ์ผ์, ๋ถ๋ณ์ ์์ ์ค๋์ค ์ํ ์ฒญํฌ๋ฅผ ๋ํ๋
๋๋ค. ์ด๊ฒ์ ํน์ ์์ ์ ์ค๋์ค ์ ํธ ์งํญ์ ๋ํ๋ด๋ ์ซ์๋ค์ ๋นฝ๋นฝํ๊ณ ๊ตฌ์กฐํ๋ ๋ฐฐ์ด์ด๋ผ๊ณ ์๊ฐํ๋ฉด ๋ฉ๋๋ค. ์ฃผ๋ก Web Audio Graph ๋ด์์ ์ฌ์์ ์ํด ์ฌ์ฉ๋๋ AudioBuffer์ ๋ฌ๋ฆฌ, AudioData๋ ์ ์ฐํ๊ณ ์ง์ ์ ์ธ ์กฐ์ ๋ฐ WebCodecs์ ๋์ฝ๋ ๋ฐ ์ธ์ฝ๋์์ ์ํธ ์ด์ฉ์ฑ์ ์ํด ์ค๊ณ๋์์ต๋๋ค.
AudioData์ ์ฃผ์ ์์ฑ
๊ฐ AudioData ๊ฐ์ฒด์๋ ํฌํจ๋ ์์ ์ค๋์ค ์ํ์ ์ค๋ช
ํ๋ ํ์ ๋ฉํ๋ฐ์ดํฐ๊ฐ ํจ๊ป ์ ๊ณต๋ฉ๋๋ค:
format: ์ํ ํฌ๋งท์ ๋ํ๋ด๋ ๋ฌธ์์ด (์:'f32-planar','s16-interleaved'). ์ด๋ ๋ฐ์ดํฐ ํ์ (float32, int16 ๋ฑ)๊ณผ ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์(ํ๋ฉดํ ๋๋ ์ธํฐ๋ฆฌ๋ธํ)์ ์๋ ค์ค๋๋ค.sampleRate: ์ด๋น ์ค๋์ค ์ํ ์ (์: 44100 Hz, 48000 Hz).numberOfChannels: ์ค๋์ค ์ฑ๋ ์ (์: ๋ชจ๋ ธ๋ 1, ์คํ ๋ ์ค๋ 2).numberOfFrames: ์ด ํน์ AudioData์ฒญํฌ์ ์๋ ์ด ์ค๋์ค ํ๋ ์ ์. ํ๋ ์์ ๊ฐ ์ฑ๋์ ๋ํ ํ๋์ ์ํ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.duration: ์ค๋์ค ๋ฐ์ดํฐ์ ์ง์ ์๊ฐ(๋ง์ดํฌ๋ก์ด).timestamp: ์ด ์ค๋์ค ๋ฐ์ดํฐ ์ฒญํฌ๊ฐ ์ ์ฒด ๋ฏธ๋์ด ์คํธ๋ฆผ์ ์์์ ๊ธฐ์ค์ผ๋ก ์ธ์ ์์๋๋์ง๋ฅผ ๋ํ๋ด๋ ํ์์คํฌํ(๋ง์ดํฌ๋ก์ด). ๋๊ธฐํ์ ๋งค์ฐ ์ค์ํฉ๋๋ค.
์ํ ํฌ๋งท๊ณผ ๋ ์ด์์ ์ดํดํ๊ธฐ
format ์์ฑ์ ์์ ๋ฐ์ดํธ๋ฅผ ์ด๋ป๊ฒ ํด์ํ ์ง๋ฅผ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ์ค์ํฉ๋๋ค:
- ๋ฐ์ดํฐ ํ์
: ๊ฐ ์ํ์ ์ซ์ ํํ์ ์ง์ ํฉ๋๋ค. ์ผ๋ฐ์ ์ธ ํ์
์ผ๋ก๋
f32(32๋นํธ ๋ถ๋์์์ ),s16(16๋นํธ ๋ถํธ ์๋ ์ ์),u8(8๋นํธ ๋ถํธ ์๋ ์ ์) ๋ฑ์ด ์์ต๋๋ค.f32์ ๊ฐ์ ๋ถ๋์์์ ํฌ๋งท์ ๋ ๋์ ๋์ ๋ฒ์์ ์ ๋ฐ๋ ๋๋ฌธ์ ์ฒ๋ฆฌ์ ์ข ์ข ์ ํธ๋ฉ๋๋ค. - ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์:
-interleaved: ํ ์์ ์ ์ฌ๋ฌ ์ฑ๋ ์ํ๋ค์ด ์ฐ์์ ์ผ๋ก ์ ์ฅ๋ฉ๋๋ค. ์คํ ๋ ์ค(L, R)์ ๊ฒฝ์ฐ, ์์๋ L0, R0, L1, R1, L2, R2, ... ๋ฑ์ด ๋ฉ๋๋ค. ์ด๋ ๋ง์ ์๋น์ ์ค๋์ค ํฌ๋งท์์ ํํ ๋ณผ ์ ์์ต๋๋ค.-planar: ํ ์ฑ๋์ ๋ชจ๋ ์ํ์ด ํจ๊ป ์ ์ฅ๋ ํ, ๋ค์ ์ฑ๋์ ๋ชจ๋ ์ํ์ด ์ด์ด์ง๋๋ค. ์คํ ๋ ์ค์ ๊ฒฝ์ฐ, L0, L1, L2, ..., R0, R1, R2, ...๊ฐ ๋ฉ๋๋ค. ์ด ๋ ์ด์์์ ๊ฐ๋ณ ์ฑ๋ ๋ฐ์ดํฐ์ ๋ ์ฝ๊ฒ ์ ๊ทผํ ์ ์์ด ์ ํธ ์ฒ๋ฆฌ์ ์ข ์ข ์ ํธ๋ฉ๋๋ค.
ํฌ๋งท ์์: 'f32-planar', 's16-interleaved', 'u8-planar'.
AudioData ์์ฑ ๋ฐ ์กฐ์ํ๊ธฐ
AudioData ์์
์ ์ฃผ๋ก ๋ ๊ฐ์ง ์์
, ์ฆ ์ธ์คํด์ค ์์ฑ๊ณผ ๋ฐ์ดํฐ ๋ณต์ฌ๋ฅผ ํฌํจํฉ๋๋ค. AudioData ๊ฐ์ฒด๋ ๋ถ๋ณ์ด๋ฏ๋ก, ์์ ์ ์ํด์๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
1. AudioData ์ธ์คํด์คํ
์์ฑ์๋ฅผ ์ฌ์ฉํ์ฌ AudioData ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ๋ฉํ๋ฐ์ดํฐ์ ์์ ์ํ ๋ฐ์ดํฐ ์์ฒด๊ฐ ํฌํจ๋ ๊ฐ์ฒด๊ฐ ํ์ํ๋ฉฐ, ๋ฐ์ดํฐ๋ ์ข
์ข
TypedArray๋ ArrayBuffer ๋ทฐ๋ก ์ ๊ณต๋ฉ๋๋ค.
์ธ๋ถ ์์ค, ์๋ฅผ ๋ค์ด ์น์์ผ ์คํธ๋ฆผ์์ ๊ฐ์ ธ์จ ์์ 16๋นํธ ๋ถํธ ์๋ ์ ์(s16) ์ธํฐ๋ฆฌ๋ธ ์คํ
๋ ์ค ์ค๋์ค ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ์๋ก ๋ค์ด ๋ณด๊ฒ ์ต๋๋ค:
const sampleRate = 48000;
const numberOfChannels = 2; // ์คํ
๋ ์ค
const frameCount = 1024; // ํ๋ ์ ์
const timestamp = 0; // ๋ง์ดํฌ๋ก์ด
// rawAudioBytes๊ฐ ์ธํฐ๋ฆฌ๋ธ๋ s16 ๋ฐ์ดํฐ๋ฅผ ํฌํจํ๋ ArrayBuffer๋ผ๊ณ ๊ฐ์ ํฉ๋๋ค
// ์: ๋คํธ์ํฌ ์คํธ๋ฆผ ๋๋ ์์ฑ๋ ์ฝํ
์ธ ๋ก๋ถํฐ.
// ์์ฐ์ ์ํด ๋๋ฏธ ArrayBuffer๋ฅผ ์์ฑํด ๋ณด๊ฒ ์ต๋๋ค.
const rawAudioBytes = new ArrayBuffer(frameCount * numberOfChannels * 2); // s16 ์ํ ๋น 2๋ฐ์ดํธ
const dataView = new DataView(rawAudioBytes);
// ์ผ์ชฝ ๋ฐ ์ค๋ฅธ์ชฝ ์ฑ๋์ ๋ํ ๋๋ฏธ ์ฌ์ธํ ๋ฐ์ดํฐ๋ก ์ฑ์๋๋ค
for (let i = 0; i < frameCount; i++) {
const sampleL = Math.sin(i * 0.1) * 32767; // s16์ ์ต๋๊ฐ์ 32767
const sampleR = Math.cos(i * 0.1) * 32767;
dataView.setInt16(i * 4, sampleL, true); // L ์ฑ๋์ ๋ํ ๋ฆฌํ ์๋์ (์คํ์
i*4)
dataView.setInt16(i * 4 + 2, sampleR, true); // R ์ฑ๋์ ๋ํ ๋ฆฌํ ์๋์ (์คํ์
i*4 + 2)
}
const audioData = new AudioData({
format: 's16-interleaved',
sampleRate: sampleRate,
numberOfChannels: numberOfChannels,
numberOfFrames: frameCount,
timestamp: timestamp,
data: rawAudioBytes
});
console.log('์์ฑ๋ AudioData:', audioData);
// ์ถ๋ ฅ์ AudioData ๊ฐ์ฒด์ ๊ทธ ์์ฑ์ ๋ณด์ฌ์ค๋๋ค.
์์ฑ์์ data ์์ฑ์ ์ฃผ๋ชฉํ์ธ์. ์ง์ ๋ format๊ณผ layout์ ๋ฐ๋ผ ์ค์ ์ํ ๊ฐ์ ํฌํจํ๋ ArrayBuffer ๋๋ TypedArray๋ฅผ ๊ธฐ๋ํฉ๋๋ค.
2. AudioData์์ ๋ฐ์ดํฐ ๋ณต์ฌํ๊ธฐ: copyTo ๋ฉ์๋
AudioData ๊ฐ์ฒด ๋ด์ ์์ ์ํ์ ์ ๊ทผํ๋ ค๋ฉด copyTo() ๋ฉ์๋๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ฉด AudioData์ ์ผ๋ถ๋ฅผ ์์ ์ ArrayBuffer๋ TypedArray๋ก ๋ณต์ฌํ ์ ์์ผ๋ฉฐ, ํฌ๋งท, ๋ ์ด์์, ์ฑ๋ ์ ํ์ ์ ์ฐํ๊ฒ ์ ์ดํ ์ ์์ต๋๋ค.
copyTo()๋ ์ฆ์์์ ๋ณํ์ ์ํํ ์ ์๊ธฐ ๋๋ฌธ์ ๋งค์ฐ ๊ฐ๋ ฅํฉ๋๋ค. ์๋ฅผ ๋ค์ด, s16-interleaved ํฌ๋งท์ AudioData๊ฐ ์์ง๋ง ์ค๋์ค ํจ๊ณผ ์๊ณ ๋ฆฌ์ฆ์ ์ํด f32-planar๋ก ์ฒ๋ฆฌํด์ผ ํ ์ ์์ต๋๋ค. copyTo()๋ ์ด ๋ณํ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
๋ฉ์๋ ์๊ทธ๋์ฒ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
copyTo(destination: BufferSource, options: AudioDataCopyToOptions): void;
์ฌ๊ธฐ์ BufferSource๋ ์ผ๋ฐ์ ์ผ๋ก TypedArray(์: Float32Array, Int16Array)์
๋๋ค. AudioDataCopyToOptions ๊ฐ์ฒด์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
format: ์ํ๋ ์ถ๋ ฅ ์ํ ํฌ๋งท (์:'f32-planar').layout: ์ํ๋ ์ถ๋ ฅ ์ฑ๋ ๋ ์ด์์ ('interleaved'๋๋'planar').planeIndex: ํ๋ฉดํ ๋ ์ด์์์ ๊ฒฝ์ฐ, ๋ณต์ฌํ ์ฑ๋ ๋ฐ์ดํฐ๋ฅผ ์ง์ ํฉ๋๋ค.frameOffset: ๋ณต์ฌ๋ฅผ ์์ํ ์์คAudioData์ ์์ ํ๋ ์ ์ธ๋ฑ์ค.frameCount: ๋ณต์ฌํ ํ๋ ์ ์.
์ด์ ์ ์์ฑํ audioData ๊ฐ์ฒด์์ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ๋, f32-planar๋ก ๋ณํํด ๋ณด๊ฒ ์ต๋๋ค:
// f32-planar ๋ฐ์ดํฐ์ ํ์ํ ํฌ๊ธฐ ๊ณ์ฐ
// ํ๋ฉดํ์ ๊ฒฝ์ฐ ๊ฐ ์ฑ๋์ ๋ณ๋์ ํ๋ฉด์
๋๋ค.
// ์ด numberOfFrames * sizeof(float32) * numberOfChannels ๋ฐ์ดํธ๋ฅผ ์ ์ฅํด์ผ ํ์ง๋ง,
// ํ ๋ฒ์ ํ๋์ ํ๋ฉด๋ง ๋ณต์ฌํ ๊ฒ์
๋๋ค.
const bytesPerSample = Float32Array.BYTES_PER_ELEMENT; // f32๋ 4๋ฐ์ดํธ
const framesPerPlane = audioData.numberOfFrames;
const planarChannelSize = framesPerPlane * bytesPerSample;
// ๊ฐ ์ฑ๋(ํ๋ฉด)์ ๋ํ TypedArray ์์ฑ
const leftChannelData = new Float32Array(framesPerPlane);
const rightChannelData = new Float32Array(framesPerPlane);
// ์ผ์ชฝ ์ฑ๋ ๋ณต์ฌ (ํ๋ฉด 0)
audioData.copyTo(leftChannelData, {
format: 'f32-planar',
layout: 'planar',
planeIndex: 0,
frameOffset: 0,
frameCount: framesPerPlane
});
// ์ค๋ฅธ์ชฝ ์ฑ๋ ๋ณต์ฌ (ํ๋ฉด 1)
audioData.copyTo(rightChannelData, {
format: 'f32-planar',
layout: 'planar',
planeIndex: 1,
frameOffset: 0,
frameCount: framesPerPlane
});
console.log('์ผ์ชฝ ์ฑ๋ (์ฒ์ 10๊ฐ ์ํ):', leftChannelData.slice(0, 10));
console.log('์ค๋ฅธ์ชฝ ์ฑ๋ (์ฒ์ 10๊ฐ ์ํ):', rightChannelData.slice(0, 10));
// ์์
์ด ๋๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ํด์ ๋ฅผ ์ํด AudioData๋ฅผ ๋ซ๋ ๊ฒ์ ์์ง ๋ง์ธ์
audioData.close();
์ด ์๋ copyTo()๊ฐ ์์ ์ค๋์ค ๋ฐ์ดํฐ๋ฅผ ์ผ๋ง๋ ์ ์ฐํ๊ฒ ๋ณํํ ์ ์๋์ง๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด ๊ธฐ๋ฅ์ ์ปค์คํ
์ค๋์ค ํจ๊ณผ, ๋ถ์ ์๊ณ ๋ฆฌ์ฆ์ ๊ตฌํํ๊ฑฐ๋, ํน์ ๋ฐ์ดํฐ ํฌ๋งท์ ๊ธฐ๋ํ๋ ๋ค๋ฅธ API๋ WebAssembly ๋ชจ๋์ ์ํด ๋ฐ์ดํฐ๋ฅผ ์ค๋นํ๋ ๋ฐ ๊ธฐ๋ณธ์ด ๋ฉ๋๋ค.
์ค์ฉ์ ์ธ ์ฌ์ฉ ์ฌ๋ก ๋ฐ ์ ํ๋ฆฌ์ผ์ด์
AudioData๊ฐ ์ ๊ณตํ๋ ์ธ๋ถํ๋ ์ ์ด๋ ์น ๋ธ๋ผ์ฐ์ ๋ด์์ ์ง์ ์๋ง์ ๊ณ ๊ธ ์ค๋์ค ์ ํ๋ฆฌ์ผ์ด์
์ ๊ฐ๋ฅํ๊ฒ ํ์ฌ ๋ฏธ๋์ด ์ ์์์ ์ ๊ทผ์ฑ์ ์ด๋ฅด๊ธฐ๊น์ง ๋ค์ํ ์ฐ์
๋ถ์ผ์์ ํ์ ์ ์ด์งํฉ๋๋ค.
1. ์ค์๊ฐ ์ค๋์ค ์ฒ๋ฆฌ ๋ฐ ํจ๊ณผ
AudioData๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์๋ ํ์ค Web Audio API ๋
ธ๋๋ฅผ ํตํด์๋ ์ฌ์ฉํ ์ ์๋ ์ปค์คํ
์ค์๊ฐ ์ค๋์ค ํจ๊ณผ๋ฅผ ๊ตฌํํ ์ ์์ต๋๋ค. ์คํกํ๋ฆ์ ํ ๊ฐ๋ฐ์๊ฐ ํ์
์์
์ ์ ํ๋ซํผ์ ๊ตฌ์ถํ๋ค๊ณ ์์ํด ๋ณด์ญ์์ค:
- ์ปค์คํ
๋ฆฌ๋ฒ๋ธ/๋๋ ์ด: ๋ค์ด์ค๋
AudioDataํ๋ ์์ ์ฒ๋ฆฌํ๊ณ , ์ ๊ตํ ์ปจ๋ณผ๋ฃจ์ ์๊ณ ๋ฆฌ์ฆ(์๋ง๋ WebAssembly๋ก ์ต์ ํ๋)์ ์ ์ฉํ ๋ค์, ์ถ๋ ฅ ๋๋ ์ฌ์ธ์ฝ๋ฉ์ ์ํด ์๋ก์ดAudioData๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. - ๊ณ ๊ธ ๋ ธ์ด์ฆ ๊ฐ์: ์์ ์ค๋์ค ์ํ์ ๋ถ์ํ์ฌ ๋ฐฐ๊ฒฝ ์์์ ์๋ณํ๊ณ ์ ๊ฑฐํจ์ผ๋ก์จ ์น ๊ธฐ๋ฐ ํ์๋ ๋ น์ ๋๊ตฌ์ ๋ ๊นจ๋ํ ์ค๋์ค๋ฅผ ์ ๊ณตํฉ๋๋ค.
- ๋์ ์ดํ๋ผ์ด์ ์ด์ : ์ค๋์ค ์ฝํ ์ธ ์ ํ๋ ์ ๋จ์๋ก ์ ์ํ๋ ์์ ์ ์ ๋ฐ๋๋ฅผ ๊ฐ์ง ๋ค์ค ๋ฐด๋ EQ๋ฅผ ๊ตฌํํฉ๋๋ค.
2. ์ปค์คํ ์ค๋์ค ์ฝ๋ฑ ๋ฐ ํธ๋์ค์ฝ๋ฉ
WebCodecs๋ ๋ฏธ๋์ด์ ๋์ฝ๋ฉ๊ณผ ์ธ์ฝ๋ฉ์ ์ฉ์ดํ๊ฒ ํฉ๋๋ค. AudioData๋ ๊ทธ ๋ค๋ฆฌ ์ญํ ์ ํฉ๋๋ค. ์์ธ์ ํ ํ์ฌ๋ ์ด์ ์ง์ฐ ํต์ ์ ์ํ ๋
์ ์ค๋์ค ์ฝ๋ฑ์ ๊ตฌํํ๊ฑฐ๋, ํน์ ๋คํธ์ํฌ ์กฐ๊ฑด์ ๋ง๊ฒ ์ค๋์ค๋ฅผ ํธ๋์ค์ฝ๋ฉํด์ผ ํ ์ ์์ต๋๋ค:
- ํด๋ผ์ด์ธํธ ์ธก ํธ๋์ค์ฝ๋ฉ: MP3 ์คํธ๋ฆผ์ ์์ ํ์ฌ
AudioDecoder๋ฅผ ์ฌ์ฉํดAudioData๋ก ๋์ฝ๋ฉํ๊ณ , ์ผ๋ถ ์ฒ๋ฆฌ๋ฅผ ์ ์ฉํ ๋ค์,AudioEncoder๋ฅผ ์ฌ์ฉํ์ฌ Opus์ ๊ฐ์ ๋ ๋์ญํญ ํจ์จ์ ์ธ ํฌ๋งท์ผ๋ก ์ฌ์ธ์ฝ๋ฉํ๋ ๋ชจ๋ ์์ ์ ๋ธ๋ผ์ฐ์ ๋ด์์ ์ํํฉ๋๋ค. - ์ปค์คํ
์์ถ: ์์
AudioData๋ฅผ ๊ฐ์ ธ์ ์ปค์คํ ์์ถ ์๊ณ ๋ฆฌ์ฆ(์: WebAssembly์์)์ ์ ์ฉํ ๋ค์, ๋ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํจ์ผ๋ก์จ ์๋ก์ด ์ค๋์ค ์์ถ ๊ธฐ์ ์ ์คํํฉ๋๋ค.
3. ๊ณ ๊ธ ์ค๋์ค ๋ถ์ ๋ฐ ๋จธ์ ๋ฌ๋
์ค๋์ค ์ฝํ
์ธ ์ ๋ํ ๊น์ ํต์ฐฐ๋ ฅ์ด ํ์ํ ์ ํ๋ฆฌ์ผ์ด์
์ ์ํด AudioData๋ ์์์ฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. ์ํ์ธ๋ฃจ์ ํ ์ฐ๊ตฌ์์ด ์์
์ ๋ณด ๊ฒ์์ ์ํ ์น ๊ธฐ๋ฐ ๋๊ตฌ๋ฅผ ๊ฐ๋ฐํ๋ค๊ณ ์๊ฐํด ๋ณด์ญ์์ค:
- ์์ฑ ์ธ์ ์ ์ฒ๋ฆฌ: ์์ ์ํ์ ์ถ์ถํ๊ณ , ํน์ง ์ถ์ถ(์: MFCC)์ ์ํํ ๋ค์, ์์ฑ ๋ช ๋ น์ด๋ ์ ์ฌ๋ฅผ ์ํด ํด๋ผ์ด์ธํธ ์ธก ๋จธ์ ๋ฌ๋ ๋ชจ๋ธ์ ์ง์ ๊ณต๊ธํฉ๋๋ค.
- ์์
๋ถ์: ์คํํธ๋ผ ๋ถ์, ์จ์
๊ฐ์ง ๋ฐ ๊ธฐํ ์ค๋์ค ํน์ง์ ์ํด
AudioData๋ฅผ ์ฒ๋ฆฌํ์ฌ ํ ํฌ, ํค ๋๋ ํน์ ์ ๊ธฐ๋ฅผ ์๋ณํฉ๋๋ค. - ์๋ฆฌ ์ด๋ฒคํธ ๊ฐ์ง: ์ค์๊ฐ ์ค๋์ค ์คํธ๋ฆผ์์ ํน์ ์๋ฆฌ(์: ์๋, ๋๋ฌผ ์ธ์์๋ฆฌ)๋ฅผ ๊ฐ์งํ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํฉ๋๋ค.
4. ์น ๊ธฐ๋ฐ ๋์งํธ ์ค๋์ค ์ํฌ์คํ ์ด์ (DAW)
์น ๋ธ๋ผ์ฐ์ ์์ ์์ ํ ์คํ๋๋ ๋ชจ๋ ๊ธฐ๋ฅ์ ๊ฐ์ถ DAW์ ๊ฟ์ด ๊ทธ ์ด๋ ๋๋ณด๋ค ๊ฐ๊น์์ก์ต๋๋ค. AudioData๋ ์ด๋ฅผ ์ํ ์ด์์
๋๋ค. ์ค๋ฆฌ์ฝ ๋ฐธ๋ฆฌ์ ํ ์คํํธ์
์ ์ ๋ฌธ์ ์ธ ๊ธฐ๋ฅ์ ๊ฐ์ถ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฐ ์ค๋์ค ํธ์ง๊ธฐ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค:
- ๋นํ๊ดด ํธ์ง: ์ค๋์ค ํ์ผ์ ๋ก๋ํ๊ณ ,
AudioDataํ๋ ์์ผ๋ก ๋์ฝ๋ฉํ๊ณ ,AudioData๊ฐ์ฒด๋ฅผ ์กฐ์ํ์ฌ ํธ์ง(์๋ฅด๊ธฐ, ๋ฏน์ฑ, ํจ๊ณผ)์ ์ ์ฉํ ๋ค์, ๋ด๋ณด๋ผ ๋ ์ฌ์ธ์ฝ๋ฉํฉ๋๋ค. - ๋ฉํฐํธ๋ ๋ฏน์ฑ: ์ฌ๋ฌ
AudioData์คํธ๋ฆผ์ ๊ฒฐํฉํ๊ณ , ๊ฒ์ธ๊ณผ ํจ๋์ ์ ์ฉํ๋ฉฐ, ์๋ฒ๋ฅผ ์ค๊ฐ๋ ๊ณผ์ ์์ด ์ต์ข ๋ฏน์ค๋ฅผ ๋ ๋๋งํฉ๋๋ค. - ์ํ ์์ค ์กฐ์: ๋ํด๋ฆฌํน, ํผ์น ์์ ๋๋ ์ ๋ฐํ ์งํญ ์กฐ์ ๊ณผ ๊ฐ์ ์์ ์ ์ํด ๊ฐ๋ณ ์ค๋์ค ์ํ์ ์ง์ ์์ ํฉ๋๋ค.
5. ๊ฒ์ ๋ฐ VR/AR์ ์ํ ์ธํฐ๋ํฐ๋ธ ์ค๋์ค
๋ชฐ์
ํ ๊ฒฝํ์ ์ข
์ข
๋งค์ฐ ๋์ ์ด๊ณ ๋ฐ์์ฑ์ด ๋ฐ์ด๋ ์ค๋์ค๋ฅผ ํ์๋ก ํฉ๋๋ค. ๊ตํ ์ ํ ๊ฒ์ ์คํ๋์ค๋ AudioData๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ํ์ฉํ ์ ์์ต๋๋ค:
- ์ ์ฐจ์ ์ค๋์ค ์์ฑ: ๊ฒ์ ์ํ์ ๋ฐ๋ผ ์ค์๊ฐ์ผ๋ก ์ฃผ๋ณ ์๋ฆฌ, ์ํฅ ํจ๊ณผ ๋๋ ์์
์ ์์๋ฅผ ์์ฑํ์ฌ ์ฌ์์ ์ํด
AudioData๊ฐ์ฒด๋ก ์ง์ ๋ง๋ญ๋๋ค. - ํ๊ฒฝ ์ค๋์ค: ์์ ์ค๋์ค ํ๋ ์์ ์ฒ๋ฆฌํ์ฌ ๊ฐ์ ํ๊ฒฝ์ ๊ธฐํํ์ ๊ตฌ์กฐ์ ๊ธฐ๋ฐํ ์ค์๊ฐ ์ํฅ ๋ชจ๋ธ๋ง ๋ฐ ์ํฅ ํจ๊ณผ๋ฅผ ์ ์ฉํฉ๋๋ค.
- ๊ณต๊ฐ ์ค๋์ค: 3D ๊ณต๊ฐ์์ ์๋ฆฌ์ ์์น๋ฅผ ์ ๋ฐํ๊ฒ ์ ์ดํ๋ฉฐ, ์ด๋ ์ข ์ข ์์ ์ค๋์ค์ ์ฑ๋๋ณ ์ฒ๋ฆฌ๋ฅผ ํฌํจํฉ๋๋ค.
๋ค๋ฅธ ์น API์์ ํตํฉ
AudioData๋ ์ง๊ณต ์ํ์ ์กด์ฌํ์ง ์์ต๋๋ค. ๊ฐ๋ ฅํ ๋ฉํฐ๋ฏธ๋์ด ์๋ฃจ์
์ ๋ง๋ค๊ธฐ ์ํด ๋ค๋ฅธ ๋ธ๋ผ์ฐ์ API์ ๊ฐ๋ ฅํ๊ฒ ์๋์ง ํจ๊ณผ๋ฅผ ๋
๋๋ค.
Web Audio API (AudioContext)
AudioData๊ฐ ์ ์์ค ์ ์ด๋ฅผ ์ ๊ณตํ๋ ๋ฐ๋ฉด, Web Audio API๋ ๊ณ ์์ค ๋ผ์ฐํ
๋ฐ ๋ฏน์ฑ์ ํ์ํฉ๋๋ค. ๋์ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค:
AudioData์์AudioBuffer๋ก:AudioData๋ฅผ ์ฒ๋ฆฌํ ํ,AudioBuffer๋ฅผ ์์ฑํ์ฌ(AudioContext.createBuffer()์ฌ์ฉ ๋ฐ ์ฒ๋ฆฌ๋ ๋ฐ์ดํฐ ๋ณต์ฌ) Web Audio ๊ทธ๋ํ ๋ด์์ ์ฌ์ํ๊ฑฐ๋ ์ถ๊ฐ ์กฐ์ํ ์ ์์ต๋๋ค.AudioBuffer์์AudioData๋ก:AudioContext์์ ์ค๋์ค๋ฅผ ์บก์ฒํ๋ ๊ฒฝ์ฐ(์:ScriptProcessorNode๋๋AudioWorklet์ฌ์ฉ),getChannelData()์ ์์ ์ถ๋ ฅ์ ์ธ์ฝ๋ฉ ๋๋ ์์ธํ ํ๋ ์ ๋จ์ ๋ถ์์ ์ํดAudioData๊ฐ์ฒด๋ก ๋ํํ ์ ์์ต๋๋ค.AudioWorklet๊ณผAudioData:AudioWorklet์ ๋ฉ์ธ ์ค๋ ๋ ์ธ๋ถ์์ ์ปค์คํ , ์ ์ง์ฐ ์ค๋์ค ์ฒ๋ฆฌ๋ฅผ ์ํํ๋ ๋ฐ ์ด์์ ์ ๋๋ค. ์คํธ๋ฆผ์AudioData๋ก ๋์ฝ๋ฉํ๊ณ , ์ด๋ฅผAudioWorklet์ ์ ๋ฌํ ๋ค์, ์ฒ๋ฆฌ๋ ์๋ก์ดAudioData๋ฅผ ์ถ๋ ฅํ๊ฑฐ๋ Web Audio ๊ทธ๋ํ์ ๊ณต๊ธํ ์ ์์ต๋๋ค.
MediaRecorder API
MediaRecorder API๋ ์น์บ ์ด๋ ๋ง์ดํฌ๋กํฐ๊ณผ ๊ฐ์ ์์ค์์ ์ค๋์ค ๋ฐ ๋น๋์ค๋ฅผ ์บก์ฒํ ์ ์๊ฒ ํฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ธ์ฝ๋ฉ๋ ์ฒญํฌ๋ฅผ ์ถ๋ ฅํ์ง๋ง, ์ผ๋ถ ๊ณ ๊ธ ๊ตฌํ์์๋ ์ฆ๊ฐ์ ์ธ ์ฒ๋ฆฌ๋ฅผ ์ํด AudioData๋ก ๋ณํํ ์ ์๋ ์์ ์คํธ๋ฆผ์ ๋ํ ์ ๊ทผ์ ํ์ฉํ ์ ์์ต๋๋ค.
Canvas API
์ค๋์ค๋ฅผ ์๊ฐํํ์ธ์! copyTo()๋ฅผ ์ฌ์ฉํ์ฌ ์์ ์ํ์ ์ถ์ถํ ํ, Canvas API๋ฅผ ์ฌ์ฉํ์ฌ ํํ, ์คํํธ๋ก๊ทธ๋จ ๋๋ ๊ธฐํ ์ค๋์ค ๋ฐ์ดํฐ์ ์๊ฐ์ ํํ์ ์ค์๊ฐ์ผ๋ก ๊ทธ๋ฆด ์ ์์ต๋๋ค. ์ด๋ ์ค๋์ค ํธ์ง๊ธฐ, ์์
ํ๋ ์ด์ด ๋๋ ์ง๋จ ๋๊ตฌ์ ํ์์ ์
๋๋ค.
// 'leftChannelData'๊ฐ AudioData.copyTo()์์ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค๊ณ ๊ฐ์
const canvas = document.getElementById('audioCanvas');
const ctx = canvas.getContext('2d');
function drawWaveform(audioDataArray) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(0, canvas.height / 2);
const step = canvas.width / audioDataArray.length;
for (let i = 0; i < audioDataArray.length; i++) {
const x = i * step;
// ์ค๋์ค ์ํ(๋ณดํต -1์์ 1)์ ์บ๋ฒ์ค ๋์ด์ ๋งคํ
const y = (audioDataArray[i] * (canvas.height / 2) * 0.8) + (canvas.height / 2);
ctx.lineTo(x, y);
}
ctx.stroke();
}
// leftChannelData์ ๋ณต์ฌํ ํ:
// drawWaveform(leftChannelData);
WebAssembly (Wasm)
๊ณ์ฐ ์ง์ฝ์ ์ธ ์ค๋์ค ์๊ณ ๋ฆฌ์ฆ(์: ๊ณ ๊ธ ํํฐ, ๋ณต์กํ ์ ํธ ์ฒ๋ฆฌ, ์ปค์คํ
์ฝ๋ฑ)์ ๊ฒฝ์ฐ, WebAssembly๋ ๊ท์คํ ํํธ๋์
๋๋ค. ์์ ArrayBuffer ๋ทฐ(AudioData.copyTo()์์ ํ์)๋ฅผ ๊ณ ์ฑ๋ฅ ์ฒ๋ฆฌ๋ฅผ ์ํด Wasm ๋ชจ๋์ ์ ๋ฌํ ๋ค์, ์์ ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํ์ฌ ์๋ก์ด AudioData ๊ฐ์ฒด๋ก ๋ค์ ๋ํํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด ์ ์ธ๊ณ ๊ฐ๋ฐ์๋ค์ ์น ํ๊ฒฝ์ ๋ ๋์ง ์๊ณ ๋ ๊น๋ค๋ก์ด ์ค๋์ค ์์ ์ ๋ํด ๋ค์ดํฐ๋ธ์ ์ ์ฌํ ์ฑ๋ฅ์ ํ์ฉํ ์ ์์ต๋๋ค. ๋ฒ ๋ฅผ๋ฆฐ์ ํ ์ค๋์ค ํ๋ฌ๊ทธ์ธ ๊ฐ๋ฐ์๊ฐ ์์ ์ C++ VST ์๊ณ ๋ฆฌ์ฆ์ ๋ธ๋ผ์ฐ์ ๊ธฐ๋ฐ ๋ฐฐํฌ๋ฅผ ์ํด WebAssembly๋ก ํฌํ ํ๋ ๊ฒ์ ์์ํด ๋ณด์ญ์์ค.
SharedArrayBuffer ๋ฐ Web Workers
์ค๋์ค ์ฒ๋ฆฌ, ํนํ ์์ ์ํ์ ๋ค๋ฃจ๋ ๊ฒ์ CPU ์ง์ฝ์ ์ผ ์ ์์ต๋๋ค. ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ์ ๋ฐฉ์งํ๊ณ ์ํํ ์ฌ์ฉ์ ๊ฒฝํ์ ๋ณด์ฅํ๊ธฐ ์ํด Web Workers๋ ํ์์ ์
๋๋ค. ํฐ AudioData ์ฒญํฌ๋ ์ฐ์์ ์ธ ์คํธ๋ฆผ์ ๋ค๋ฃฐ ๋, SharedArrayBuffer๋ ๋ฉ์ธ ์ค๋ ๋์ ์์ปค ๊ฐ์ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ตํ์ ์ฉ์ดํ๊ฒ ํ์ฌ ๋ณต์ฌ ์ค๋ฒํค๋๋ฅผ ์ต์ํํ ์ ์์ต๋๋ค.
AudioDecoder ๋๋ AudioEncoder๋ ์ผ๋ฐ์ ์ผ๋ก ๋น๋๊ธฐ์ ์ผ๋ก ์๋ํ๋ฉฐ ์์ปค์์ ์คํ๋ ์ ์์ต๋๋ค. AudioData๋ฅผ ์์ปค์ ์ ๋ฌํ๊ณ ์ฒ๋ฆฌํ ๋ค์, ์ฒ๋ฆฌ๋ AudioData๋ฅผ ๋ค์ ๋ฐ์ ์ ์์ผ๋ฉฐ, ์ด ๋ชจ๋ ๊ณผ์ ์ด ๋ฉ์ธ ์ค๋ ๋ ์ธ๋ถ์์ ์ด๋ฃจ์ด์ ธ ์ค์ํ UI ์์
์ ๋ํ ๋ฐ์์ฑ์ ์ ์งํฉ๋๋ค.
์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ ๋ฐ ๋ชจ๋ฒ ์ฌ๋ก
์์ ์ค๋์ค ๋ฐ์ดํฐ๋ก ์์
ํ๋ ค๋ฉด ์ฑ๋ฅ๊ณผ ์์ ๊ด๋ฆฌ์ ์ธ์ฌํ ์ฃผ์๊ฐ ํ์ํฉ๋๋ค. WebCodecs AudioData ์ ํ๋ฆฌ์ผ์ด์
์ ์ต์ ํํ๊ธฐ ์ํ ์ฃผ์ ๋ชจ๋ฒ ์ฌ๋ก๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
1. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ: AudioData.close()
AudioData ๊ฐ์ฒด๋ ๊ณ ์ ๋ ๋ฉ๋ชจ๋ฆฌ ์ฒญํฌ๋ฅผ ๋ํ๋
๋๋ค. ๊ฒฐ์ ์ ์ผ๋ก, ์ด๋ค์ ์ค์ฝํ๋ฅผ ๋ฒ์ด๋ ๋ ์๋์ผ๋ก ๊ฐ๋น์ง ์ปฌ๋ ์
๋์ง ์์ต๋๋ค. AudioData ๊ฐ์ฒด ์ฌ์ฉ์ ๋ง์ณค์ ๋ ๋ฐ๋์ audioData.close()๋ฅผ ๋ช
์์ ์ผ๋ก ํธ์ถํ์ฌ ๊ธฐ๋ณธ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํด์ ํด์ผ ํฉ๋๋ค. ๊ทธ๋ ๊ฒ ํ์ง ์์ผ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ๊ณ ์ ํ๋ฆฌ์ผ์ด์
์ฑ๋ฅ์ด ์ ํ๋๋ฉฐ, ํนํ ์ฅ์๊ฐ ์คํ๋๋ ์ ํ๋ฆฌ์ผ์ด์
์ด๋ ์ฐ์์ ์ธ ์ค๋์ค ์คํธ๋ฆผ์ ์ฒ๋ฆฌํ๋ ๊ฒฝ์ฐ ๋์ฑ ๊ทธ๋ ์ต๋๋ค.
const audioData = new AudioData({ /* ... */ });
// ... audioData ์ฌ์ฉ ...
audioData.close(); // ๋ฉ๋ชจ๋ฆฌ ํด์
2. ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ ๋ฐฉ์ง
๋ณต์กํ ์ค๋์ค ์ฒ๋ฆฌ๋ ์ด์์ ์ผ๋ก Web Worker๋ AudioWorklet์์ ์ด๋ฃจ์ด์ ธ์ผ ํฉ๋๋ค. WebCodecs๋ฅผ ํตํ ๋์ฝ๋ฉ ๋ฐ ์ธ์ฝ๋ฉ ์์
์ ๋ณธ์ง์ ์ผ๋ก ๋น๋๊ธฐ์ ์ด๋ฉฐ ์ฝ๊ฒ ์คํ๋ก๋ํ ์ ์์ต๋๋ค. ์์ AudioData๋ฅผ ๋ฐ์ผ๋ฉด ๋ฉ์ธ ์ค๋ ๋๊ฐ ๊ณผ๋ถํ๋๊ธฐ ์ ์ ์ฆ์ ์์ปค์ ์ ๋ฌํ์ฌ ์ฒ๋ฆฌํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
3. copyTo() ์์
์ต์ ํ
copyTo()๋ ํจ์จ์ ์ด์ง๋ง, ๋ฐ๋ณต์ ์ธ ํธ์ถ์ด๋ ๋๋์ ๋ฐ์ดํฐ ๋ณต์ฌ๋ ์ฌ์ ํ ๋ณ๋ชฉ ํ์์ด ๋ ์ ์์ต๋๋ค. ๋ถํ์ํ ๋ณต์ฌ๋ฅผ ์ต์ํํ์ญ์์ค. ์ฒ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ์ด ํน์ ํฌ๋งท(์: f32-planar)์ผ๋ก ์ง์ ์์
ํ ์ ์๋ค๋ฉด, ํด๋น ํฌ๋งท์ผ๋ก ํ ๋ฒ๋ง ๋ณต์ฌํ๋๋ก ํ์ญ์์ค. ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋์์ ๋ํด TypedArray ๋ฒํผ๋ฅผ ์ฌ์ฌ์ฉํ๊ณ , ๋งค ํ๋ ์๋ง๋ค ์ ๋ฒํผ๋ฅผ ํ ๋นํ์ง ๋ง์ญ์์ค.
4. ์ ์ ํ ์ํ ํฌ๋งท ๋ฐ ๋ ์ด์์ ์ ํ
์ฒ๋ฆฌ ์๊ณ ๋ฆฌ์ฆ๊ณผ ๊ฐ์ฅ ์ ๋ง๋ ํฌ๋งท(์: f32-planar ๋ s16-interleaved)์ ์ ํํ์ญ์์ค. f32์ ๊ฐ์ ๋ถ๋์์์ ํฌ๋งท์ ์ ์ ์ฐ์ฐ์์ ๋ฐ์ํ ์ ์๋ ์์ํ ์ค๋ฅ๋ฅผ ํผํ ์ ์์ด ์ํ์ ์ฐ์ฐ์ ์ผ๋ฐ์ ์ผ๋ก ์ ํธ๋ฉ๋๋ค. ํ๋ฉดํ ๋ ์ด์์์ ์ข
์ข
์ฑ๋๋ณ ์ฒ๋ฆฌ๋ฅผ ๋จ์ํํฉ๋๋ค.
5. ๋ค์ํ ์ํ ๋ ์ดํธ ๋ฐ ์ฑ๋ ์ ์ฒ๋ฆฌ
์ค์ ์๋๋ฆฌ์ค์์ ๋ค์ด์ค๋ ์ค๋์ค(์: ๋ค๋ฅธ ๋ง์ดํฌ, ๋คํธ์ํฌ ์คํธ๋ฆผ)๋ ๋ค์ํ ์ํ ๋ ์ดํธ๋ ์ฑ๋ ๊ตฌ์ฑ์ ๊ฐ์ง ์ ์์ต๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ AudioData์ ์ปค์คํ
์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ์ฌ ์ค๋์ค ํ๋ ์์ ์ผ๊ด๋ ๋์ ํฌ๋งท์ผ๋ก ๋ฆฌ์ํ๋งํ๊ฑฐ๋ ๋ฆฌ๋ฏน์ฑํจ์ผ๋ก์จ ์ด๋ฌํ ๋ณํ๋ฅผ ๊ฒฌ๊ณ ํ๊ฒ ์ฒ๋ฆฌํ ์ ์์ด์ผ ํฉ๋๋ค.
6. ์ค๋ฅ ์ฒ๋ฆฌ
ํนํ ์ธ๋ถ ๋ฐ์ดํฐ๋ ํ๋์จ์ด๋ฅผ ๋ค๋ฃฐ ๋๋ ํญ์ ๊ฒฌ๊ณ ํ ์ค๋ฅ ์ฒ๋ฆฌ๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค. WebCodecs ์์
์ ๋น๋๊ธฐ์ ์ด๋ฉฐ ์ง์๋์ง ์๋ ์ฝ๋ฑ, ์์๋ ๋ฐ์ดํฐ ๋๋ ์์ ์ ํ์ผ๋ก ์ธํด ์คํจํ ์ ์์ต๋๋ค. try...catch ๋ธ๋ก๊ณผ ํ๋ก๋ฏธ์ค ๊ฑฐ๋ถ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋ฅ๋ฅผ ์ฐ์ํ๊ฒ ๊ด๋ฆฌํ์ญ์์ค.
๊ณผ์ ๋ฐ ํ๊ณ์
WebCodecs AudioData๋ ๊ฐ๋ ฅํ์ง๋ง, ๊ณผ์ ๊ฐ ์๋ ๊ฒ์ ์๋๋๋ค:
- ๋ธ๋ผ์ฐ์ ์ง์: ๋น๊ต์ ์๋ก์ด API์ด๋ฏ๋ก ๋ธ๋ผ์ฐ์ ์ง์์ด ๋ค๋ฅผ ์ ์์ต๋๋ค. ๋์ ๊ณ ๊ฐ์ ๋ํ ํธํ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด ํญ์ `caniuse.com`์ ํ์ธํ๊ฑฐ๋ ๊ธฐ๋ฅ ๊ฐ์ง๋ฅผ ์ฌ์ฉํ์ญ์์ค. ํ์ฌ๋ ํฌ๋ก๋ฏธ์ ๊ธฐ๋ฐ ๋ธ๋ผ์ฐ์ (ํฌ๋กฌ, ์ฃ์ง, ์คํ๋ผ)์์ ์ ์ง์๋๋ฉฐ ํ์ด์ดํญ์ค์์๋ ์ ์ฐจ ์ง์์ด ํ๋๋๊ณ ์์ง๋ง, ์นํท(์ฌํ๋ฆฌ)์ ์์ง ๋ฐ๋ผ์ก๋ ์ค์ ๋๋ค.
- ๋ณต์ก์ฑ: ์ ์์ค API์
๋๋ค. ์ด๋ ๋ ๋ง์ ์ฝ๋, ๋ ๋ช
์์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ(
close()), ๊ทธ๋ฆฌ๊ณ ๊ณ ์์ค API์ ๋นํด ์ค๋์ค ๊ฐ๋ ์ ๋ํ ๋ ๊น์ ์ดํด๋ฅผ ์๋ฏธํฉ๋๋ค. ๋จ์ํจ์ ์ ์ด๋ ฅ๊ณผ ๋ง๋ฐ๊พผ ๊ฒ์ ๋๋ค. - ์ฑ๋ฅ ๋ณ๋ชฉ: ๊ณ ์ฑ๋ฅ์ ๊ฐ๋ฅํ๊ฒ ํ์ง๋ง, ์๋ชป๋ ๊ตฌํ(์: ๋ฉ์ธ ์ค๋ ๋ ์ฐจ๋จ, ๊ณผ๋ํ ๋ฉ๋ชจ๋ฆฌ ํ ๋น/ํด์ )์ ํนํ ์ฑ๋ฅ์ด ๋ฎ์ ์ฅ์น๋ ๋งค์ฐ ๋์ ํด์๋์ ์ค๋์ค์์ ๋น ๋ฅด๊ฒ ์ฑ๋ฅ ๋ฌธ์ ๋ก ์ด์ด์ง ์ ์์ต๋๋ค.
- ๋๋ฒ๊น : ์ ์์ค ์ค๋์ค ์ฒ๋ฆฌ ๋๋ฒ๊น ์ ๋ณต์กํ ์ ์์ต๋๋ค. ์์ ์ํ ๋ฐ์ดํฐ๋ฅผ ์๊ฐํํ๊ณ , ๋นํธ ๊น์ด๋ฅผ ์ดํดํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ถ์ ํ๋ ค๋ฉด ์ ๋ฌธ์ ์ธ ๊ธฐ์ ๊ณผ ๋๊ตฌ๊ฐ ํ์ํฉ๋๋ค.
AudioData์ ํจ๊ปํ๋ ์น ์ค๋์ค์ ๋ฏธ๋
WebCodecs AudioData๋ ๋ธ๋ผ์ฐ์ ์์ ์ค๋์ค์ ํ๊ณ๋ฅผ ๋ํ๋ ค๋ ์น ๊ฐ๋ฐ์๋ค์๊ฒ ์ค์ํ ์ง์ ์ ์๋ฏธํฉ๋๋ค. ์ด๋ ํ๋ ๋ค์ดํฐ๋ธ ๋ฐ์คํฌํฑ ์ ํ๋ฆฌ์ผ์ด์
์ด๋ ๋ณต์กํ ์๋ฒ ์ธก ์ธํ๋ผ์๋ง ๊ตญํ๋์๋ ๊ธฐ๋ฅ์ ๋ํ ์ ๊ทผ์ ๋ฏผ์ฃผํํฉ๋๋ค.
๋ธ๋ผ์ฐ์ ์ง์์ด ์ฑ์ํ๊ณ ๊ฐ๋ฐ์ ๋๊ตฌ๊ฐ ๋ฐ์ ํจ์ ๋ฐ๋ผ, ํ์ ์ ์ธ ์น ๊ธฐ๋ฐ ์ค๋์ค ์ ํ๋ฆฌ์ผ์ด์ ์ ํญ๋ฐ์ ์ธ ์ฆ๊ฐ๋ฅผ ๊ธฐ๋ํ ์ ์์ต๋๋ค. ์ฌ๊ธฐ์๋ ๋ค์์ด ํฌํจ๋ฉ๋๋ค:
- ์ ๋ฌธ๊ฐ๊ธ ์น DAW: ์ ์ธ๊ณ ์์ ๊ฐ์ ํ๋ก๋์๊ฐ ๋ธ๋ผ์ฐ์ ์์ ์ง์ ๋ณต์กํ ์ค๋์ค ํ๋ก์ ํธ๋ฅผ ํ์ ํ๊ณ ๋ง๋ค ์ ์๊ฒ ํฉ๋๋ค.
- ๊ณ ๊ธ ํต์ ํ๋ซํผ: ๋ ธ์ด์ฆ ์บ์ฌ๋ง, ์์ฑ ํฅ์ ๋ฐ ์ ์ํ ์คํธ๋ฆฌ๋ฐ์ ์ํ ์ปค์คํ ์ค๋์ค ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ถฅ๋๋ค.
- ํ๋ถํ ๊ต์ก ๋๊ตฌ: ์ํธ์์ฉ์ ์ธ ์ค์๊ฐ ์์ ๋ฅผ ํตํด ์ค๋์ค ๊ณตํ, ์์ ์ด๋ก ๋ฐ ์ ํธ ์ฒ๋ฆฌ๋ฅผ ๊ฐ๋ฅด์นฉ๋๋ค.
- ๋ ๋ชฐ์ ๊ฐ ์๋ ๊ฒ์ ๋ฐ XR ๊ฒฝํ: ๋์ ์ด๊ณ ๊ณ ํ์ง์ ์ค๋์ค๊ฐ ๊ฐ์ ํ๊ฒฝ์ ์ํํ๊ฒ ์ ์ํฉ๋๋ค.
์์ ์ค๋์ค ์ํ๋ก ์์ ํ ์ ์๋ ๋ฅ๋ ฅ์ ์น์์ ๊ฐ๋ฅํ ๊ฒ์ ๊ทผ๋ณธ์ ์ผ๋ก ๋ฐ๊พธ์ด, ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ๋ ์ํธ์์ฉ์ ์ด๊ณ , ๋ฏธ๋์ด๊ฐ ํ๋ถํ๋ฉฐ, ์ฑ๋ฅ์ด ๋ฐ์ด๋ ์ฌ์ฉ์ ๊ฒฝํ์ ์ํ ๊ธธ์ ์ด์ด์ค๋๋ค.
๊ฒฐ๋ก
WebCodecs AudioData๋ ํ๋ ์น ์ค๋์ค ๊ฐ๋ฐ์ ์ํ ๊ฐ๋ ฅํ๊ณ ๊ธฐ์ด์ ์ธ ์ธํฐํ์ด์ค์
๋๋ค. ๊ฐ๋ฐ์์๊ฒ ์์ ์ค๋์ค ์ํ์ ๋ํ ์ ๋ก ์๋ ์ ๊ทผ ๊ถํ์ ๋ถ์ฌํ์ฌ, ๋ธ๋ผ์ฐ์ ๋ด์์ ๋ณต์กํ ์ฒ๋ฆฌ, ์ปค์คํ
์ฝ๋ฑ ๊ตฌํ ๋ฐ ์ ๊ตํ ๋ถ์ ๊ธฐ๋ฅ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. ์ค๋์ค ๊ธฐ์ด์ ๋ํ ๊น์ ์ดํด์ ์ ์คํ ์์ ๊ด๋ฆฌ๊ฐ ํ์ํ์ง๋ง, ์ต์ฒจ๋จ ๋ฉํฐ๋ฏธ๋์ด ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋๋ ๋ฐ ์ด๋ฆฌ๋ ๊ธฐํ๋ ์์ฒญ๋ฉ๋๋ค.
AudioData๋ฅผ ๋ง์คํฐํจ์ผ๋ก์จ, ์ฌ๋ฌ๋ถ์ ๋จ์ํ ์ฝ๋๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋๋ผ ๊ฐ์ฅ ๊ทผ๋ณธ์ ์ธ ์์ค์์ ์๋ฆฌ๋ฅผ ์กฐ์จํ๊ณ ์์ผ๋ฉฐ, ์ ์ธ๊ณ ์ฌ์ฉ์์๊ฒ ๋ ํ๋ถํ๊ณ ์ํธ์์ฉ์ ์ด๋ฉฐ ๊ณ ๋๋ก ๋ง์ถคํ๋ ์ค๋์ค ๊ฒฝํ์ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ์์์ ํ์ ๋ฐ์๋ค์ด๊ณ , ๊ทธ ์ ์ฌ๋ ฅ์ ํ์ํ๋ฉฐ, ์ฐจ์ธ๋ ์น ์ค๋์ค ํ์ ์ ๊ธฐ์ฌํ์ญ์์ค.